\documentclass{article}

\title{dDist Aflevering G4}

\author{The Shadow Dread Lord Master-Gods\\of the\\Dark Evil Dead Doom Legion\\ \\Jeppe Hansen 20061245\\Steffen Jensen 20061335\\Asger Feldthaus 20061089}

\newenvironment{code}{\begin{quote}\ttfamily}{\end{quote}}

\newcommand{\uri}[1]{\texttt{#1}}
\newcommand{\headerfield}[1]{\texttt{#1}}

\setlength{\parskip}{6 pt}

\begin{document}

\maketitle

\section{ID generation}
When a remote object is returned from the server, an ID string is sent to represent it. These IDs are on the form "id:xxxx" where xxxx is an integer. The IDs are generated on an on-demand basis when a Remote object is returned, and encapsulated in a RemoteObject object.

\section{Reliability and performance}
We have enabled the total ordering mode in JGroups to ensure that every method call is executed in the same order on every server.

For example, suppose client A sends getAccount(F) to server A', and client B sends getAccount(G) to server B' simultaneously. If FIFO or no ordering is used, server A' will assign account F id:1, and server B' will assign account G id:1. Total ordering ensures that either server will postpone its own call until it has executed the call from the other.

Alternatively, we could use a seperate channel for ID assignment using total ordering, such that the communication that does not require total ordering can be interleaved. 

This is a special case because withdraw() and deposit() are associative operations, that is, you can change their order without affecting the result. Therefore, we COULD use a non-ordered channel to manage these calls, but in a general case it has to be totally ordered.

A \emph{read}-method is annotated with @ReadOnly, which prevents our API from broadcasting the method call to the other servers. Note that getAccount is NOT a read-method, because it also creates accounts. The annotation only needs to be present on the server-side, in the implementation of a Remote class. The annotation is purely an optimization, so the programmer may ommit it entirely, and add it later when performance becomes an issue.

getAccount is currently not a read-method because it creates an account on the server. But in case the account already exists, the broadcast is redundant since we know nothing will happen. This is the result of a bad design choice: It should really have been split into a createAccount method, and a "real" getAccount method, which simply returns null if the account does not exist.

If a cluster of servers, with an even distribution of clients, receive mainly \emph{read}-methods, the calls do not need to be distributed among the servers, and we can expect a performance improvement. \emph{Update}-methods, however, require that every server executes it, so the total workload is accumulated instead of distributed. On top of that, there is some delay from the total ordering used to propagate update calls.

\section{Locks}
If more complicated operations should be made on an account, such as adding interest, we may want to have locks to do it properly. For example, client A and client B may at the same time want to add 10\% interest to an account. They both call getBalance() to find that the account has 1000 DKK, and then call deposit(100 * 0.10). The sequence of events is then:
\begin{code}
A.getBalance
B.getBalance\\
A.deposit\\
B.deposit\\
\end{code}
The account ends up with 1200 DKK, but if the clients had locked the account first, it would have had 1210 DKK.

The traditional thread-lock scheme in Java is not appropriate, because the client might crash without unlocking the object. For this reason, we need at least a timeout on a lock. It is also important that there is a reasonably high upper limit on the number of threads running on a server, since it might otherwise become full of waiting threads, and a release request might not get through.

Instead, we can have methods like lockAccount() return an account object that is valid until Account.release() is called on it. In this way, it is impossible to get a reference to the account object without locking it first. lockAccount() will wait until the account is unlocked, and so will the client because it uses synchronous RPC. We have not added locks in our implementation.



\end{document}